package cn.iocoder.yudao.module.call.service.ivrknowledgeissue;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.call.controller.admin.ivrlearn.vo.IvrLearnSaveReqVO;
import cn.iocoder.yudao.module.call.controller.open.ivrlearn.vo.IvrLearnSaveByFlowReqVO;
import cn.iocoder.yudao.module.call.dal.dataobject.ivrflow.IvrFlowDO;
import cn.iocoder.yudao.module.call.dal.dataobject.ivrknowledgegroup.IvrKnowledgeGroupDO;
import cn.iocoder.yudao.module.call.dal.dataobject.ivrknowledgeissuevoice.IvrKnowledgeIssueVoiceDO;
import cn.iocoder.yudao.module.call.dal.mysql.ivrflow.IvrFlowMapper;
import cn.iocoder.yudao.module.call.dal.mysql.ivrknowledgegroup.IvrKnowledgeGroupMapper;
import cn.iocoder.yudao.module.call.dal.mysql.ivrknowledgeissuevoice.IvrKnowledgeIssueVoiceMapper;
import cn.iocoder.yudao.module.call.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.call.service.ivrlearn.IvrLearnService;
import cn.iocoder.yudao.module.call.util.TtsHuoShanUtil;
import cn.iocoder.yudao.module.call.util.TtsUtil;
import cn.iocoder.yudao.module.system.api.extend.ExtendApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

import org.springframework.validation.annotation.Validated;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import cn.iocoder.yudao.module.call.controller.admin.ivrknowledgeissue.vo.*;
import cn.iocoder.yudao.module.call.dal.dataobject.ivrknowledgeissue.IvrKnowledgeIssueDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.call.dal.mysql.ivrknowledgeissue.IvrKnowledgeIssueMapper;
import org.springframework.web.multipart.MultipartFile;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.call.enums.ErrorCodeConstants.*;

/**
 * ivr-知识库问题 Service 实现类
 *
 * @author 数创万维
 */
@Service
@Validated
public class IvrKnowledgeIssueServiceImpl implements IvrKnowledgeIssueService {

    @Resource
    private IvrKnowledgeIssueMapper ivrKnowledgeIssueMapper;

    @Resource
    private IvrKnowledgeIssueVoiceMapper voiceMapper;

    @Resource
    private ExtendApi extendApi;

    @Resource
    private IvrFlowMapper ivrFlowMapper;


    @Resource
    private IvrKnowledgeIssueVoiceMapper ivrKnowledgeIssueVoiceMapper;

    @Resource
    private IvrKnowledgeGroupMapper ivrKnowledgeGroupMapper;


    @Resource
    private IvrLearnService ivrLearnService;

    @Override
    public void delKnowledgeIssueVoiceById(Long id) {
        IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO = voiceMapper.selectById(id);
        if (null == ivrKnowledgeIssueVoiceDO) {
            return;
        }
        if (StringUtils.isNotEmpty(ivrKnowledgeIssueVoiceDO.getLocalPath())) {
            LambdaUpdateWrapper<IvrKnowledgeIssueVoiceDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(IvrKnowledgeIssueVoiceDO::getId, ivrKnowledgeIssueVoiceDO.getId());
            updateWrapper.set(IvrKnowledgeIssueVoiceDO::getRecordPath,null);
            updateWrapper.set(IvrKnowledgeIssueVoiceDO::getLocalPath,null);
            updateWrapper.set(IvrKnowledgeIssueVoiceDO::getRecordContent,null);
            ivrKnowledgeIssueVoiceMapper.update(updateWrapper);
        }
    }
    @Override
    public void delKnowledgeIssueVoiceByFlowId(Long flowId) {
        List<IvrKnowledgeIssueDO> ivrKnowledgeIssueDOS = ivrKnowledgeIssueMapper.selectList(IvrKnowledgeIssueDO::getFlowId, flowId);
        if (CollUtil.isEmpty(ivrKnowledgeIssueDOS)) {
            return ;
        }
        for (IvrKnowledgeIssueDO ivrKnowledgeIssueDO : ivrKnowledgeIssueDOS) {
            List<IvrKnowledgeIssueVoiceDO> ivrKnowledgeIssueVoiceDOS = voiceMapper.selectList(IvrKnowledgeIssueVoiceDO::getIssueId, ivrKnowledgeIssueDO.getId());
            if (CollUtil.isEmpty(ivrKnowledgeIssueVoiceDOS)) {
                continue;
            }
            for (IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO : ivrKnowledgeIssueVoiceDOS) {
                if (StringUtils.isNotEmpty(ivrKnowledgeIssueVoiceDO.getLocalPath())) {
                    LambdaUpdateWrapper<IvrKnowledgeIssueVoiceDO> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(IvrKnowledgeIssueVoiceDO::getId, ivrKnowledgeIssueVoiceDO.getId());
                    updateWrapper.set(IvrKnowledgeIssueVoiceDO::getRecordPath,null);
                    updateWrapper.set(IvrKnowledgeIssueVoiceDO::getLocalPath,null);
                    updateWrapper.set(IvrKnowledgeIssueVoiceDO::getRecordContent,null);
                    ivrKnowledgeIssueVoiceMapper.update(updateWrapper);
                }
            }
        }
    }

    /**
     * 单个生成话术语音
     * @param createReqVO
     */
    @Override
    public void knowledgeIssueVoiceByIdCreate(IvrKnowledgeIssueVoiceDO createReqVO) {
        IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO1 = voiceMapper.selectById(createReqVO.getId());
        if (ivrKnowledgeIssueVoiceDO1 == null) {
            return;
        }

        if (StringUtils.isEmpty(ivrKnowledgeIssueVoiceDO1.getLocalPath())) {
            ivrKnowledgeIssueVoiceDO1.setTimbreType(createReqVO.getTimbreType());
            ivrKnowledgeIssueVoiceDO1.setVolume(createReqVO.getVolume());
            ivrKnowledgeIssueVoiceDO1.setSpeed(createReqVO.getSpeed());
            ivrKnowledgeIssueVoiceDO1.setPitch(createReqVO.getPitch());
            ivrKnowledgeIssueVoiceDO1.setVoiceType(createReqVO.getVoiceType());
            createVoice(ivrKnowledgeIssueVoiceDO1);
        }
    }

    @Override
    public void knowledgeIssueVoiceByIdCreateManual(IvrKnowledgeIssueVoiceDO createReqVO) {
        IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO1 = voiceMapper.selectById(createReqVO.getId());
        createVoiceManual(ivrKnowledgeIssueVoiceDO1, createReqVO.getFile());
    }
    @Override
    public void knowledgeIssueVoiceListCreate(IvrKnowledgeIssueVoiceDO createReqVO) {
        List<IvrKnowledgeIssueDO> ivrKnowledgeIssueDOS = ivrKnowledgeIssueMapper.selectList(IvrKnowledgeIssueDO::getFlowId, createReqVO.getFlowId());
        if (CollUtil.isEmpty(ivrKnowledgeIssueDOS)) {
            return ;
        }
        for (IvrKnowledgeIssueDO ivrKnowledgeIssueDO : ivrKnowledgeIssueDOS) {
            List<IvrKnowledgeIssueVoiceDO> ivrKnowledgeIssueVoiceDOS = voiceMapper.selectList(IvrKnowledgeIssueVoiceDO::getIssueId, ivrKnowledgeIssueDO.getId());
            if (CollUtil.isEmpty(ivrKnowledgeIssueVoiceDOS)) {
                continue;
            }
            for (IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO : ivrKnowledgeIssueVoiceDOS) {
                if (StringUtils.isEmpty(ivrKnowledgeIssueVoiceDO.getLocalPath())) {
                    ivrKnowledgeIssueVoiceDO.setTimbreType(createReqVO.getTimbreType());
                    ivrKnowledgeIssueVoiceDO.setVolume(createReqVO.getVolume());
                    ivrKnowledgeIssueVoiceDO.setSpeed(createReqVO.getSpeed());
                    ivrKnowledgeIssueVoiceDO.setPitch(createReqVO.getPitch());
                    ivrKnowledgeIssueVoiceDO.setVoiceType(createReqVO.getVoiceType());
                    createVoice(ivrKnowledgeIssueVoiceDO);
                }
            }
        }
    }
    @Override
    public List<JSONObject> KnowledgeIssueByFlowId(Long flowId) {
        List<IvrKnowledgeIssueDO> ivrKnowledgeIssueDOS = ivrKnowledgeIssueMapper.selectList(IvrKnowledgeIssueDO::getFlowId, flowId);
        if (CollUtil.isEmpty(ivrKnowledgeIssueDOS)) {
            return null;
        }
        List<JSONObject> contentList = new ArrayList<>();
        for (IvrKnowledgeIssueDO ivrKnowledgeIssueDO : ivrKnowledgeIssueDOS) {
            List<IvrKnowledgeIssueVoiceDO> ivrKnowledgeIssueVoiceDOS = voiceMapper.selectList(IvrKnowledgeIssueVoiceDO::getIssueId, ivrKnowledgeIssueDO.getId());
            if (CollUtil.isEmpty(ivrKnowledgeIssueVoiceDOS)) {
                continue;
            }
            for (IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO : ivrKnowledgeIssueVoiceDOS) {
                JSONObject jsonResult = new JSONObject();
                jsonResult.set("id", ivrKnowledgeIssueVoiceDO.getId());
                jsonResult.set("name", ivrKnowledgeIssueDO.getTitle());
                jsonResult.set("content", ivrKnowledgeIssueVoiceDO.getRecordDescription());
                if (StringUtils.isEmpty(ivrKnowledgeIssueVoiceDO.getLocalPath())) {
                    jsonResult.set("isVoice", 0);
                }else{
                    jsonResult.set("isVoice", 1);
                    jsonResult.set("filePath", ivrKnowledgeIssueVoiceDO.getRecordPath());
                }
                contentList.add(jsonResult);
            }
        }
        return contentList;
    }

    private IvrKnowledgeIssueVoiceDO createVoiceManual(IvrKnowledgeIssueVoiceDO createReqVO,MultipartFile file) {
        byte[] baiDuTtsByte = null;
        try {
            baiDuTtsByte = mp3ToWavByteArray(file);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String base64String = Base64.getEncoder().encodeToString(baiDuTtsByte);
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("byte", base64String);
            put("type", "file");
        }};
        extendApi.setDomain("");
        JSONObject agentState = extendApi.request("/index/ivrUpload", JSONUtil.toJsonStr(params));
        String filePath = agentState.getStr("filePath");
        String localPath = agentState.getStr("localPath");
        createReqVO.setRecordPath(filePath);
        createReqVO.setLocalPath(localPath);
//        createReqVO.setRecordContent(createReqVO.getRecordDescription());
        IvrKnowledgeIssueVoiceDO updateObj = BeanUtils.toBean(createReqVO, IvrKnowledgeIssueVoiceDO.class);
        ivrKnowledgeIssueVoiceMapper.updateById(updateObj);
        extendApi.setDomain("");
        extendApi.clearMatchCache(updateObj.getFlowId());
        return createReqVO;
    }

    public static byte[] mp3ToWavByteArray(MultipartFile mp3File) throws Exception {
        String originalFilename = mp3File.getOriginalFilename();
        if (originalFilename == null || !originalFilename.contains(".")) {
            throw new IllegalArgumentException("Invalid file name.");
        }

        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        // 如果是 .wav 文件，直接返回 byte[]
        if (".wav".equals(suffix)) {
            try {
                return mp3File.getBytes();
            } catch (IOException e) {
                throw new RuntimeException("Failed to read the content of the WAV file.", e);
            }
        }
        // 将 MultipartFile 转换为 InputStream
        InputStream mp3InputStream = mp3File.getInputStream();

        // 使用 BufferedInputStream 以确保支持 mark/reset
        BufferedInputStream bufferedInputStream = new BufferedInputStream(mp3InputStream);

        // 获取音频输入流
        AudioInputStream mp3AudioStream = AudioSystem.getAudioInputStream(bufferedInputStream);

        // 获取音频格式
        AudioFormat baseFormat = mp3AudioStream.getFormat();

        // 定义目标音频格式
        AudioFormat targetFormat = new AudioFormat(
                AudioFormat.Encoding.PCM_SIGNED,
                baseFormat.getSampleRate(),
                16,  // 16-bit PCM
                baseFormat.getChannels(),
                baseFormat.getChannels() * 2,  // 每通道字节数
                baseFormat.getSampleRate(),
                false  // 不使用大端字节序
        );

        // 转换为 PCM 格式
        AudioInputStream pcmAudioStream = AudioSystem.getAudioInputStream(targetFormat, mp3AudioStream);

        // 写入 ByteArrayOutputStream
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            // 使用 AudioSystem 将 PCM 格式音频流写入 WAV 格式并返回字节数组
            AudioSystem.write(pcmAudioStream, AudioFileFormat.Type.WAVE, baos);
            return baos.toByteArray();
        } catch (Exception e) {
            // 打印日志或抛出自定义异常
            System.err.println("[mp3ToWavByteArray] 转换失败: " + e.getMessage());
            e.printStackTrace();
            return null;
        } finally {
            // 确保流被关闭
            if (mp3AudioStream != null) {
                try {
                    mp3AudioStream.close();
                } catch (IOException e) {
                    System.err.println("[mp3ToWavByteArray] 关闭 mp3AudioStream 失败: " + e.getMessage());
                }
            }
            if (pcmAudioStream != null) {
                try {
                    pcmAudioStream.close();
                } catch (IOException e) {
                    System.err.println("[mp3ToWavByteArray] 关闭 pcmAudioStream 失败: " + e.getMessage());
                }
            }
        }
    }
    private IvrKnowledgeIssueVoiceDO createVoice(IvrKnowledgeIssueVoiceDO createReqVO) {
        if (null == createReqVO.getTimbreType() || createReqVO.getTimbreType() == 1) {
            byte[] baiDuTtsByte = TtsUtil.getKeDaXunFeiTtsBasicUrlNew(createReqVO.getRecordDescription(), createReqVO.getVoiceType(),createReqVO.getSpeed(),createReqVO.getVolume(),createReqVO.getPitch());
            String baiDuTtsByteString = Base64.getEncoder().encodeToString(baiDuTtsByte);
            Map<String, Object> params = new HashMap<String, Object>() {{
                put("ttsByte", baiDuTtsByteString);
                put("type", "tts");
            }};
            extendApi.setDomain("https://127.0.0.1:8082");
            JSONObject agentState = extendApi.request("/index/pcmToWave", JSONUtil.toJsonStr(params));
            String filePath = agentState.getStr("filePath");
            String localPath = agentState.getStr("localPath");
            createReqVO.setRecordPath(filePath);
            createReqVO.setLocalPath(localPath);
            createReqVO.setRecordContent(createReqVO.getRecordDescription());
            IvrKnowledgeIssueVoiceDO updateObj = BeanUtils.toBean(createReqVO, IvrKnowledgeIssueVoiceDO.class);
            ivrKnowledgeIssueVoiceMapper.updateById(updateObj);
            extendApi.setDomain("https://127.0.0.1:8082");
            extendApi.clearMatchCache(updateObj.getFlowId());
        }
        if (null != createReqVO.getTimbreType() && createReqVO.getTimbreType() == 2) {
//            byte[] baiDuTtsByte = TtsUtil.getHuoShanTtsBasicUrlNew(createReqVO.getRecordDescription(), createReqVO.getVoiceType(), createReqVO.getSpeed(), createReqVO.getVolume(), createReqVO.getPitch());
            byte[] baiDuTtsByte = null;
            try {
                baiDuTtsByte = TtsHuoShanUtil.synthesizeTTS(createReqVO.getRecordDescription(), createReqVO.getVoiceType(), createReqVO.getSpeed(), createReqVO.getVolume());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            String baiDuTtsByteString = Base64.getEncoder().encodeToString(baiDuTtsByte);
            Map<String, Object> params = new HashMap<String, Object>() {{
                put("byte", baiDuTtsByteString);
                put("type", "file");
            }};
            extendApi.setDomain("https://scrmextend.com:8082");
            JSONObject agentState = extendApi.request("/index/ivrUpload", JSONUtil.toJsonStr(params));
            String filePath = agentState.getStr("filePath");
            String localPath = agentState.getStr("localPath");
            createReqVO.setRecordPath(filePath);
            createReqVO.setLocalPath(localPath);
            createReqVO.setRecordContent(createReqVO.getRecordDescription());
            IvrKnowledgeIssueVoiceDO updateObj = BeanUtils.toBean(createReqVO, IvrKnowledgeIssueVoiceDO.class);
            ivrKnowledgeIssueVoiceMapper.updateById(updateObj);
            extendApi.setDomain("https://127.0.0.1:8082");
            extendApi.clearMatchCache(updateObj.getFlowId());
        }
        return createReqVO;
    }

    @Async
    @Override
    public CommonResult<Long> addIvrKnowledge(IvrLearnSaveByFlowReqVO ivrLearnSaveByFlowReqVO) {
        IvrFlowDO ivrFlowDO = ivrFlowMapper.selectById(ivrLearnSaveByFlowReqVO.getFlowId());
        if (Objects.isNull(ivrFlowDO)) {
            return error(ErrorCodeConstants.IVR_FLOW_NOT_EXISTS);
        }
        LambdaQueryWrapper<IvrKnowledgeIssueDO> issueDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
        issueDOLambdaQueryWrapper.eq(IvrKnowledgeIssueDO::getFlowId, ivrFlowDO.getId());
        issueDOLambdaQueryWrapper.eq(IvrKnowledgeIssueDO::getKeys, ivrLearnSaveByFlowReqVO.getInput());
        Long retCount = ivrKnowledgeIssueMapper.selectCount(issueDOLambdaQueryWrapper);
        if (retCount > 0) {
            return success(null);
        }
        IvrLearnSaveReqVO ivrLearnSaveReqVO = new IvrLearnSaveReqVO();
        ivrLearnSaveReqVO.setCallId(ivrLearnSaveByFlowReqVO.getCallId());
        ivrLearnSaveReqVO.setGroupId(ivrFlowDO.getGroupId());
        ivrLearnSaveReqVO.setFlowId(ivrFlowDO.getId());
        ivrLearnSaveReqVO.setNodeId(ivrLearnSaveByFlowReqVO.getNodeId());
        ivrLearnSaveReqVO.setInput(ivrLearnSaveByFlowReqVO.getInput());
        ivrLearnSaveReqVO.setKeys(ivrLearnSaveByFlowReqVO.getInput());
        ivrLearnSaveReqVO.setContent(ivrLearnSaveByFlowReqVO.getContent());
        ivrLearnSaveReqVO.setNodeName(ivrLearnSaveByFlowReqVO.getNodeName());
        ivrLearnSaveReqVO.setJumpType(ivrLearnSaveByFlowReqVO.getJumpType());
        //同步知识库分组
        LambdaQueryWrapper<IvrKnowledgeGroupDO> KnowledgeGroupQuery = new LambdaQueryWrapper<>();
        KnowledgeGroupQuery.eq(IvrKnowledgeGroupDO::getFlowId, ivrFlowDO.getId());
        KnowledgeGroupQuery.eq(IvrKnowledgeGroupDO::getName, "大模型");
        KnowledgeGroupQuery.last("limit 1");
        IvrKnowledgeGroupDO ivrKnowledgeGroupDORet = ivrKnowledgeGroupMapper.selectOne(KnowledgeGroupQuery);
        Long groupId = null;
        if (Objects.isNull(ivrKnowledgeGroupDORet)) {
            IvrKnowledgeGroupDO ivrKnowledgeGroupDO = new IvrKnowledgeGroupDO();
            ivrKnowledgeGroupDO.setFlowId(ivrFlowDO.getId());
            ivrKnowledgeGroupDO.setName("大模型");
            ivrKnowledgeGroupDO.setType(2);
            TenantUtils.execute(ivrFlowDO.getTenantId(), () -> ivrKnowledgeGroupMapper.insert(ivrKnowledgeGroupDO));
            groupId = ivrKnowledgeGroupDO.getId();
        } else {
            groupId = ivrKnowledgeGroupDORet.getId();
        }
        //同步知识库问题
        IvrKnowledgeIssueDO ivrKnowledgeIssueDO = new IvrKnowledgeIssueDO();
        ivrKnowledgeIssueDO.setTitle(ivrLearnSaveByFlowReqVO.getInput());
        ivrKnowledgeIssueDO.setKeys(ivrLearnSaveByFlowReqVO.getInput());
        extendApi.setDomain("https://127.0.0.1:8082");
        ivrKnowledgeIssueDO.setKeysPinyin(extendApi.pinyin(ivrLearnSaveByFlowReqVO.getInput()));
        ivrKnowledgeIssueDO.setJumpType(ivrLearnSaveByFlowReqVO.getJumpType());
        ivrKnowledgeIssueDO.setJumpIndex(ivrLearnSaveByFlowReqVO.getJumpId());
        ivrKnowledgeIssueDO.setKnowledgeGroupId(groupId);
        ivrKnowledgeIssueDO.setFlowId(ivrFlowDO.getId());
        ivrKnowledgeIssueDO.setKnowledgeType(1);
        ivrKnowledgeIssueDO.setType(2);
        ivrKnowledgeIssueDO.setEnableContinuousPlay(0);
        ivrKnowledgeIssueDO.setContinuousPlayNum(1);
        ivrKnowledgeIssueDO.setIsSendSms(0);
        ivrKnowledgeIssueDO.setEnableJoinBlack(0);
        TenantUtils.execute(ivrFlowDO.getTenantId(), () -> ivrKnowledgeIssueMapper.insert(ivrKnowledgeIssueDO));
        IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO = new IvrKnowledgeIssueVoiceDO();
        ivrKnowledgeIssueVoiceDO.setId(null);
        ivrKnowledgeIssueVoiceDO.setIssueId(ivrKnowledgeIssueDO.getId());
        ivrKnowledgeIssueVoiceDO.setRecordDescription(ivrLearnSaveByFlowReqVO.getContent());
        ivrKnowledgeIssueVoiceDO.setRecordContent(ivrLearnSaveByFlowReqVO.getContent());

        byte[] baiDuTtsByte = null;
        try {
            baiDuTtsByte = TtsHuoShanUtil.synthesizeTTS(ivrLearnSaveByFlowReqVO.getContent(), ivrLearnSaveByFlowReqVO.getVoiceName(), ivrLearnSaveByFlowReqVO.getSpeed(), ivrLearnSaveByFlowReqVO.getVolume());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
//        byte[] baiDuTtsByte = TtsHuoShanUtil.synthesizeTTS(ivrLearnSaveByFlowReqVO.getContent(), ivrLearnSaveByFlowReqVO.getVoiceName());
        String base64String = Base64.getEncoder().encodeToString(baiDuTtsByte);
        // 输出 Base64 字符串
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("byte", base64String);
            put("type", "file");
        }};
        extendApi.setDomain("https://scrmextend.com:8082");
        JSONObject agentState = extendApi.request("/index/ivrUpload", JSONUtil.toJsonStr(params));
        String filePath = agentState.getStr("filePath");
        String localPath = agentState.getStr("localPath");
        ivrKnowledgeIssueVoiceDO.setRecordPath(filePath);
        ivrKnowledgeIssueVoiceDO.setLocalPath(localPath);
        extendApi.addKnowledgeCache(ivrKnowledgeIssueDO.getId());

        TenantUtils.execute(ivrFlowDO.getTenantId(), () -> ivrKnowledgeIssueVoiceMapper.insert(ivrKnowledgeIssueVoiceDO));
        return success(TenantUtils.execute(ivrFlowDO.getTenantId(), () -> ivrLearnService.createIvrLearn(ivrLearnSaveReqVO)));
    }
    @Override
    public Long createIvrKnowledgeIssueList(List<IvrKnowledgeIssueSaveReqListVO> createReqVO,  Long ivrFlowId,String voiceType) {
        // 插入
        for (IvrKnowledgeIssueSaveReqListVO ivrKnowledgeIssueSaveReqListVO : createReqVO) {
            IvrKnowledgeIssueDO ivrKnowledgeIssue = BeanUtils.toBean(ivrKnowledgeIssueSaveReqListVO, IvrKnowledgeIssueDO.class);
            ivrKnowledgeIssue.setFlowId(ivrFlowId);
            ivrKnowledgeIssueMapper.insert(ivrKnowledgeIssue);
            byte[] baiDuTtsByte = TtsUtil.getKeDaXunFeiTtsBasicUrl(ivrKnowledgeIssueSaveReqListVO.getAnswerContent(), voiceType);
            String baiDuTtsByteString = Base64.getEncoder().encodeToString(baiDuTtsByte);
            Map<String, Object> params = new HashMap<String, Object>() {{
                put("ttsByte", baiDuTtsByteString);
                put("type", "tts");
            }};
            extendApi.setDomain("http://127.0.0.1:8082");
            JSONObject agentState = extendApi.request("/index/pcmToWave", JSONUtil.toJsonStr(params));
            String filePath = agentState.getStr("filePath");
            String localPath = agentState.getStr("localPath");
            IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO = new IvrKnowledgeIssueVoiceDO();
            ivrKnowledgeIssueVoiceDO.setIssueId(ivrKnowledgeIssue.getId());
            ivrKnowledgeIssueVoiceDO.setRecordDescription(ivrKnowledgeIssueSaveReqListVO.getAnswerContent());
            ivrKnowledgeIssueVoiceDO.setRecordContent(ivrKnowledgeIssueSaveReqListVO.getAnswerContent());
            ivrKnowledgeIssueVoiceDO.setLocalPath(localPath);
            ivrKnowledgeIssueVoiceDO.setRecordPath(filePath);
            voiceMapper.insert(ivrKnowledgeIssueVoiceDO);
            //更新知识库缓存
            extendApi.addKnowledgeCache(ivrKnowledgeIssue.getId());
        }
        return null;
    }
    @Override
    public Long createIvrKnowledgeIssue(IvrKnowledgeIssueSaveReqVO createReqVO) {
        // 插入
        IvrKnowledgeIssueDO ivrKnowledgeIssue = BeanUtils.toBean(createReqVO, IvrKnowledgeIssueDO.class);
        extendApi.setDomain("https://127.0.0.1:8082");
        ivrKnowledgeIssue.setKeysPinyin(extendApi.pinyin(createReqVO.getKeys()));
        ivrKnowledgeIssueMapper.insert(ivrKnowledgeIssue);
        //清理流程缓存
        extendApi.addKnowledgeCache(ivrKnowledgeIssue.getId());
        // 返回
        return ivrKnowledgeIssue.getId();
    }
    @Override
    public void updateIvrKnowledgeIssueType(IvrKnowledgeIssueSaveReqVO updateReqVO) {
        // 校验存在
        validateIvrKnowledgeIssueExists(updateReqVO.getId());
        // 更新
        LambdaQueryWrapper<IvrKnowledgeGroupDO> groupQuery = new LambdaQueryWrapper<IvrKnowledgeGroupDO>();
        groupQuery.eq(IvrKnowledgeGroupDO::getFlowId, updateReqVO.getFlowId());
        groupQuery.eq(IvrKnowledgeGroupDO::getType, 1);
        groupQuery.last("limit 1");
        IvrKnowledgeGroupDO ivrKnowledgeGroupDO = ivrKnowledgeGroupMapper.selectOne(groupQuery);
        updateReqVO.setKnowledgeGroupId(ivrKnowledgeGroupDO.getId());
        updateReqVO.setType(1);
        IvrKnowledgeIssueDO updateObj = BeanUtils.toBean(updateReqVO, IvrKnowledgeIssueDO.class);
        extendApi.setDomain("https://127.0.0.1:8082");
        updateObj.setKeysPinyin(extendApi.pinyin(updateReqVO.getKeys()));
        extendApi.clearMatchCache(updateReqVO.getFlowId());
        ivrKnowledgeIssueMapper.updateById(updateObj);
    }
    @Override
    public void updateIvrKnowledgeIssue(IvrKnowledgeIssueSaveReqVO updateReqVO) {
        // 校验存在
        validateIvrKnowledgeIssueExists(updateReqVO.getId());
        // 更新
        IvrKnowledgeIssueDO updateObj = BeanUtils.toBean(updateReqVO, IvrKnowledgeIssueDO.class);
        extendApi.setDomain("https://127.0.0.1:8082");
        updateObj.setKeysPinyin(extendApi.pinyin(updateReqVO.getKeys()));
        extendApi.clearMatchCache(updateReqVO.getFlowId());
        ivrKnowledgeIssueMapper.updateById(updateObj);
    }

    @Override
    public void deleteIvrKnowledgeIssue(Long id) {
        // 校验存在
        IvrKnowledgeIssueDO info = validateIvrKnowledgeIssueExists(id);
        extendApi.clearMatchCache(info.getFlowId());

        // 删除
        ivrKnowledgeIssueMapper.deleteById(id);
    }

    private IvrKnowledgeIssueDO validateIvrKnowledgeIssueExists(Long id) {
        IvrKnowledgeIssueDO issue = ivrKnowledgeIssueMapper.selectById(id);
        if (ivrKnowledgeIssueMapper.selectById(id) == null) {
            throw exception(IVR_KNOWLEDGE_ISSUE_NOT_EXISTS);
        }
        return issue;
    }

    @Override
    public IvrKnowledgeIssueDO getIvrKnowledgeIssue(Long id) {
        IvrKnowledgeIssueDO ivrKnowledgeIssueDO = ivrKnowledgeIssueMapper.selectById(id);
        List<IvrKnowledgeIssueVoiceDO> ivrKnowledgeIssueVoiceDOS = voiceMapper.selectList(new LambdaQueryWrapper<IvrKnowledgeIssueVoiceDO>().eq(IvrKnowledgeIssueVoiceDO::getIssueId, id));
        ivrKnowledgeIssueDO.setVoiceDOList(ivrKnowledgeIssueVoiceDOS);
        return ivrKnowledgeIssueDO;
    }

    @Override
    public PageResult<IvrKnowledgeIssueDO> getIvrKnowledgeIssuePage(IvrKnowledgeIssuePageReqVO pageReqVO) {
//        PageResult<IvrKnowledgeIssueDO> ivrKnowledgeIssueDOPageResult = ivrKnowledgeIssueMapper.selectPage(pageReqVO);
//        if (CollUtil.isNotEmpty(ivrKnowledgeIssueDOPageResult.getList())) {
//            LambdaQueryWrapper<IvrKnowledgeIssueVoiceDO> voiceQueryWrapper = new LambdaQueryWrapper<>();
//            for (IvrKnowledgeIssueDO ivrKnowledgeIssueDO : ivrKnowledgeIssueDOPageResult.getList()) {
//                voiceQueryWrapper.eq(IvrKnowledgeIssueVoiceDO::getIssueId, ivrKnowledgeIssueDO.getId());
//                Long voiceCount = voiceMapper.selectCount(voiceQueryWrapper);
//                if (voiceCount > 0) {
//                    ivrKnowledgeIssueDO.setAnswerVoice(true);
//                }
//                if (StringUtils.isNoneBlank(ivrKnowledgeIssueDO.getKeys())) {
//                    String[] parts = ivrKnowledgeIssueDO.getKeys().split(",");
//                    // 获取分组的数量
//                    ivrKnowledgeIssueDO.setKeysCount(parts.length);
//                } else {
//                    ivrKnowledgeIssueDO.setKeysCount(0);
//                }
//            }
//        }
        PageResult<IvrKnowledgeIssueDO> result = ivrKnowledgeIssueMapper.selectPage(pageReqVO);
        return result;
    }

    @Override
    public void initDefaultKnowledge() {
        List<IvrKnowledgeIssueDO> IssueDOList = TenantUtils.execute(0L, () -> ivrKnowledgeIssueMapper.selectList());
        for (IvrKnowledgeIssueDO ivrKnowledgeIssueDO : IssueDOList) {
            List<IvrKnowledgeIssueVoiceDO> ivrKnowledgeIssueVoiceDOS = voiceMapper.selectList(new LambdaQueryWrapper<IvrKnowledgeIssueVoiceDO>().eq(IvrKnowledgeIssueVoiceDO::getIssueId, ivrKnowledgeIssueDO.getId()));
            ivrKnowledgeIssueDO.setId(null);
            ivrKnowledgeIssueDO.setCreateTime(null);
            ivrKnowledgeIssueDO.setUpdater(null);
            ivrKnowledgeIssueMapper.insert(ivrKnowledgeIssueDO);
            if (CollUtil.isNotEmpty(ivrKnowledgeIssueVoiceDOS)) {
                for (IvrKnowledgeIssueVoiceDO ivrKnowledgeIssueVoiceDO : ivrKnowledgeIssueVoiceDOS) {
                    ivrKnowledgeIssueVoiceDO.setId(null);
                    ivrKnowledgeIssueVoiceDO.setIssueId(ivrKnowledgeIssueDO.getId());
                    voiceMapper.insert(ivrKnowledgeIssueVoiceDO);
                }
            }
        }
    }
}